package com.skillworld.webapp.model.course;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

import com.skillworld.webapp.model.department.Department;
import com.skillworld.webapp.model.lesson.Lesson;
import com.skillworld.webapp.model.user.User;

@Entity
@org.hibernate.annotations.BatchSize(size=10)
@Table(name="Course")
public class Course
{
    public enum Status { PENDING, ENABLED }
    
    private Long courseId;
	private Locale locale;
	private String name;
	private String description;
	private List<Lesson> lessons = new ArrayList<Lesson>();
	private User author;
	private Department department;
	private int maxStudents;
	private int vacancies;
	private Status status;

	
	protected Course()
	{ 

	}
	
    public Course(Locale locale, String name, String description, 
                    User author, Department department, int maxStudents) 
    {
		this.locale = locale;
		this.name = name;
		this.description = description;
		this.author = author;
		this.department = department;
		this.maxStudents = maxStudents;
		this.vacancies = maxStudents;
		this.status = Status.PENDING;
	}

    
	@SequenceGenerator(name="CourseIdGenerator",sequenceName="CourseSeq")
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO,generator="CourseIdGenerator")
	@Column(name="idCourse")
	public Long getCourseId() 
	{
        return courseId;
    }
    
    protected void setCourseId(Long courseId)
    {
        this.courseId = courseId;
    }

    @Column(name="locale")
    public Locale getLocale() 
    {
        return this.locale;
    }

    public void setLocale(Locale locale) 
    {
        this.locale = locale;
    }

    @Column(name="name")
    public String getName() 
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    @Column(name="description")
    public String getDescription() 
    {
        return description;
    }
    
    public void setDescription(String description) 
    {
        this.description = description;
    }

    @OneToMany(mappedBy="course",fetch=FetchType.LAZY,orphanRemoval=true)
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE})
    @OrderBy
    public List<Lesson> getLessons() 
    {
        return lessons;
    }
    
    protected void setLessons(List<Lesson> lessons)
    {
        this.lessons = lessons;
    }
    
    @ManyToOne(optional=false,fetch=FetchType.LAZY)
    @JoinColumn(name="idMaster")
    public User getAuthor() 
    {
        return author;
    }
    
    protected void setAuthor(User author) 
    {
        this.author = author;
    }

    @ManyToOne(optional=false,fetch=FetchType.LAZY)
    @JoinColumn(name="idDepartment")
    public Department getDepartment() 
    {
        return department;
    }
    
    public void setDepartment(Department department)
    {
        this.department = department;
    }
    
    @Column(name="maxStudents")
	public int getMaxStudents()
	{
        return maxStudents;
    }

    public void setMaxStudents(int maxStudents)
    {
        this.maxStudents = maxStudents;
    }

    @Column(name="vacancies")
    public int getVacancies()
    {
        return vacancies;
    }
    
    @Transient
    public boolean hasVacancies()
    {
        return vacancies > 0;
    }

    protected void setVacancies(int vacancies)
    {
        this.vacancies = vacancies;
    }

    @Enumerated(EnumType.STRING)
	@Column(name="status")
    public Status getStatus() 
	{
        return status;
    }
	
    public void setStatus(Status status) 
    {
        this.status = status;
    }
    
    @Transient
    public boolean isEnabled()
    {
        return status == Status.ENABLED;
    }
    
    
    public void newEnrollment()
    {
        vacancies--;
    }
    
    // Someone completed the course
    public void newCompletion()
    {
        vacancies++;
    }
}
